type StorageValue = string | number | boolean | object | null

const safeParse = <T,>(value: string | null): T | null => {
  if (!value) return null
  try {
    return JSON.parse(value) as T
  } catch {
    return null
  }
}

const storageImpl = {
  get<T extends StorageValue>(key: string): T | null {
    if (typeof window === 'undefined') return null
    const value = window.localStorage.getItem(key)
    return safeParse<T>(value)
  },

  set<T extends StorageValue>(key: string, value: T) {
    if (typeof window === 'undefined') return
    if (value === null || value === undefined) {
      this.remove(key)
      return
    }
    window.localStorage.setItem(key, JSON.stringify(value))
  },

  remove(key: string) {
    if (typeof window === 'undefined') return
    window.localStorage.removeItem(key)
  },
}

export const storage = storageImpl


